package org.smog.core.config.web;

import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.smog.core.config.web.model.ApiResponse;
import org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

import java.util.Arrays;
import java.util.List;

/**
 * 利用ResponseBodyAdvice统一返回值处理
 * 还可以利用 RequestBodyAdvice,ResponseBodyAdvice 进行加密解密操作
 *
 * @Description: Created by IntelliJ IDEA.
 * @project_name: smogTemp
 * @time: 2020-05-15 15:19
 * @email: 17685306043@163.com
 * @author: huangZhongYao
 */
@Slf4j
@AllArgsConstructor
@RestControllerAdvice
public class ApiResponseBodyAdvice implements ResponseBodyAdvice<Object> {

    private static final List<String> NOT_HANDLE = Arrays.asList(
            "org.smog.template.core.config.web.ExceptionHandlerController",
            "springfox.documentation.swagger.web.ApiResourceController",
            "springfox.documentation.swagger2.web.Swagger2Controller",
            "com.github.xiaoymin.swaggerbootstrapui.web.SwaggerBootstrapUiController",
            "com.github.xiaoymin.knife4j.spring.web.Knife4jController"
    );

    @Override
    public boolean supports(MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> aClass) {
        // 当前接口controller 判断controller 来决定是否包装返回值
        Class<?> zClass = methodParameter.getDeclaringClass();
        if (zClass.equals(ExceptionHandlerController.class) || zClass.equals(BasicErrorController.class)) {
            return false;
        } else {
            return !NOT_HANDLE.contains(zClass.getName());
        }
    }

    @Override
    public Object beforeBodyWrite(Object methodResult, MethodParameter methodParameter, MediaType mediaType, Class<? extends HttpMessageConverter<?>> aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {
        ApiResponse<Object> response = new ApiResponse<>();
        response.setPath(serverHttpRequest.getURI().getPath());
        response.setResult(methodResult);
        return response;
    }
}
